#include "stdafx.h"
#include "Fakes/FakeD3D11BlendState.h"
#include "Fakes/FakeD3D11Device.h"

DESCRIPTION_11_TEST_SUITE(BlendDescription)

BOOST_FIXTURE_TEST_CASE(Default, TestBlendDescription)
{
	BOOST_REQUIRE_EQUAL(FALSE, m_desc.AlphaToCoverageEnable);
	BOOST_REQUIRE_EQUAL(FALSE, m_desc.IndependentBlendEnable);
	rt::D3D11::RenderTargetBlendDescription const default_;
	for (UINT i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i)
	{
		D3D11_RENDER_TARGET_BLEND_DESC const &desc = m_desc.RenderTarget[i];
		BOOST_REQUIRE_EQUAL(default_.BlendEnable, desc.BlendEnable);
		BOOST_REQUIRE_EQUAL(default_.SrcBlend, desc.SrcBlend);
		BOOST_REQUIRE_EQUAL(default_.DestBlend, desc.DestBlend);
		BOOST_REQUIRE_EQUAL(default_.BlendOp, desc.BlendOp);
		BOOST_REQUIRE_EQUAL(default_.SrcBlendAlpha, desc.SrcBlendAlpha);
		BOOST_REQUIRE_EQUAL(default_.DestBlendAlpha, desc.DestBlendAlpha);
		BOOST_REQUIRE_EQUAL(default_.BlendOpAlpha, desc.BlendOpAlpha);
		BOOST_REQUIRE_EQUAL(default_.RenderTargetWriteMask, desc.RenderTargetWriteMask);
	}
}

#define BLEND_DESCRIPTION_TEST_CASE(type_, name_, value_) \
	DESCRIPTION_11_SETTER_TEST_CASE(type_, name_, value_, BlendDescription)

BLEND_DESCRIPTION_TEST_CASE(BOOL, AlphaToCoverageEnable, TRUE)
BLEND_DESCRIPTION_TEST_CASE(BOOL, IndependentBlendEnable, TRUE)

BOOST_FIXTURE_TEST_CASE(Create, TestBlendDescription)
{
	FakeD3D11Device device;
	device.CreateBlendStateFakeHResult = S_OK;
	FakeD3D11BlendState blendState;
	device.CreateBlendStateFakeResult = &blendState;
	ID3D11BlendState *state = m_desc.Create(&device);
	BOOST_REQUIRE(device.CreateBlendStateCalled);
	BOOST_REQUIRE_EQUAL(&m_desc, device.CreateBlendStateLastDesc);
	BOOST_REQUIRE_EQUAL(&blendState, state);
}

BOOST_FIXTURE_TEST_CASE(RenderTarget_, TestBlendDescription)
{
	rt::D3D11::RenderTargetBlendDescription target = rt::D3D11::RenderTargetBlendDescription().BlendEnable_(TRUE)
		.SrcBlend_(D3D11_BLEND_ZERO).BlendOp_(D3D11_BLEND_OP_SUBTRACT).DestBlend_(D3D11_BLEND_ONE)
		.SrcBlendAlpha_(D3D11_BLEND_ZERO).BlendOpAlpha_(D3D11_BLEND_OP_SUBTRACT).DestBlendAlpha_(D3D11_BLEND_ONE)
		.RenderTargetWriteMask_(D3D11_COLOR_WRITE_ENABLE_ALPHA);
	D3D11_RENDER_TARGET_BLEND_DESC value = m_desc.RenderTarget_(0, target).RenderTarget[0];
	BOOST_REQUIRE_EQUAL(TRUE, value.BlendEnable);
	BOOST_REQUIRE_EQUAL(D3D11_BLEND_ZERO, value.SrcBlend);
	BOOST_REQUIRE_EQUAL(D3D11_BLEND_ONE, value.DestBlend);
	BOOST_REQUIRE_EQUAL(D3D11_BLEND_OP_SUBTRACT, value.BlendOp);
	BOOST_REQUIRE_EQUAL(D3D11_BLEND_ZERO, value.SrcBlendAlpha);
	BOOST_REQUIRE_EQUAL(D3D11_BLEND_ONE, value.DestBlendAlpha);
	BOOST_REQUIRE_EQUAL(D3D11_BLEND_OP_SUBTRACT, value.BlendOpAlpha);
	BOOST_REQUIRE_EQUAL(D3D11_COLOR_WRITE_ENABLE_ALPHA, value.RenderTargetWriteMask);
}

BOOST_FIXTURE_TEST_CASE(Copy, TestBlendDescription)
{
	rt::D3D11::RenderTargetBlendDescription target = rt::D3D11::RenderTargetBlendDescription().BlendEnable_(TRUE)
		.SrcBlend_(D3D11_BLEND_ZERO).BlendOp_(D3D11_BLEND_OP_SUBTRACT).DestBlend_(D3D11_BLEND_ONE)
		.SrcBlendAlpha_(D3D11_BLEND_ZERO).BlendOpAlpha_(D3D11_BLEND_OP_SUBTRACT).DestBlendAlpha_(D3D11_BLEND_ONE)
		.RenderTargetWriteMask_(D3D11_COLOR_WRITE_ENABLE_ALPHA);
	rt::D3D11::BlendDescription copy(m_desc.AlphaToCoverageEnable_(TRUE).IndependentBlendEnable_(TRUE)
		.RenderTarget_(0, target));
#define ASSERT_MEMBER_COPIED(member_)  BOOST_REQUIRE_EQUAL(copy.member_, m_desc.member_)
	ASSERT_MEMBER_COPIED(AlphaToCoverageEnable);
	ASSERT_MEMBER_COPIED(IndependentBlendEnable);
	for (int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i)
	{
		ASSERT_MEMBER_COPIED(RenderTarget[i].BlendEnable);
		ASSERT_MEMBER_COPIED(RenderTarget[i].SrcBlend);
		ASSERT_MEMBER_COPIED(RenderTarget[i].DestBlend);
		ASSERT_MEMBER_COPIED(RenderTarget[i].BlendOp);
		ASSERT_MEMBER_COPIED(RenderTarget[i].SrcBlendAlpha);
		ASSERT_MEMBER_COPIED(RenderTarget[i].DestBlendAlpha);
		ASSERT_MEMBER_COPIED(RenderTarget[i].BlendOpAlpha);
		ASSERT_MEMBER_COPIED(RenderTarget[i].RenderTargetWriteMask);
	}
}

BOOST_AUTO_TEST_SUITE_END()
